//<<<+++OPENSOURCE
//<<<+++OPENSOURCE_LICENSE
/**
 * @addtogroup FXCODEC
 * @{
 */

/**
 * @file
 * @brief Various codec modules
 */
//<<<+++OPENSOURCE_MUST_BEGIN
#ifndef _FX_CODEC_H_
#define _FX_CODEC_H_
//<<<+++OPENSOURCE_MUST_END

//<<<+++OPENSOURCE_MUST_BEGIN
#ifndef _FXCRT_EXTENSION_
	#include "../fxcrt/fx_ext.h"
#endif
//<<<+++OPENSOURCE_MUST_END
#include "fx_codec_def.h"
#include "fx_codec_provider.h"

class CFX_DIBSource;
class ICodec_ScanlineDecoder;
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
class ICodec_ProgressiveDecoder;
//<<<+++OPENSOURCE_END
class ICodec_BasicModule;
class ICodec_FaxModule;
class ICodec_JpegModule;
class ICodec_JpxModule;
class ICodec_Jbig2Module;
class ICodec_IccModule;
class ICodec_FlateModule;
class ICodec_Jbig2Encoder;
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
class ICodec_PngModule;
class ICodec_GifModule;
class ICodec_BmpModule;
class ICodec_TiffModule;
class ICodec_WebpModule;
class ICodec_WebpEncoder;
class ICodec_JpxEncoder;
class ICodec_GifEncoder;
class ICodec_BmpEncoder;
class CFX_DIBAttribute;
//<<<+++OPENSOURCE_END
class ICodec_ScanlineDecoder;

#if defined(_FX_MANAGED_CODE_) && defined(GetLastError)
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
#undef	GetLastError
//<<<+++OPENSOURCE_END
#endif

/** 
 * @brief Foxit Codec module manager. In order to use many codec, you must create the module first. 
 */
class CCodec_ModuleMgr : public CFX_Object
{
public:
	/**
	 * Create a Codec module.
	 */
	static CCodec_ModuleMgr*	Create();

	/**
	 * Destroy the current Codec module.
	 */
	void				Destroy();

	/** 
	 * For embedded platform only: load the jbig2 decoder (on desktop it's automatically loaded) 
	 */
	void				InitJbig2Decoder();
	/** 
	 * For embedded platform only: load the jpeg2000 decoder (on desktop it's automatically loaded) 
	 */
	void				InitJpxDecoder();
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	/** 
	 * For embedded platform only: load the tiff decoder (on desktop it's automatically loaded) 
	 */
	void				InitTiffDecoder();
    /** 
	 * For embedded platform only: load the webp decoder (on desktop it's automatically loaded) 
	 */
	void				InitWebpDecoder();
	/** 
	 * For embedded platform only: load the png decoder (on desktop it's automatically loaded) 
	 */
	void				InitPngDecoder();
	/** 
	 * For embedded platform only: load the gif decoder (on desktop it's automatically loaded) 
	 */
	void				InitGifDecoder();
	/** 
	 * For embedded platform only: load the bmp decoder (on desktop it's automatically loaded) 
	 */
	void				InitBmpDecoder();
	//<<<+++OPENSOURCE_END
	
	/** 
	 * For embedded platform only: load the icc decoder (on desktop it's automatically loaded except the _ICC_NO_DECODER_ has been defined) 
	 */
	void				InitIccDecoder();

	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	/**
	 * Create a Progressive decoder.
	 * After use it, the caller should release the decoder.
	 *
	 * @return The context of the Progressive decoder.
	 */
	ICodec_ProgressiveDecoder*	CreateProgressiveDecoder();
	
	/**
	 * Create a JPX encoder.
	 * After use it, the caller should release the encoder.
	 *
	 * @param[in] pSource				The source image to be encoded
	 * @return The context of the JPX encoder.
	 */
	ICodec_JpxEncoder*			CreateJpxEncoder(const CFX_DIBSource* pSource);
	//<<<+++OPENSOURCE_END
	/**
	 * Create a JBig2 encoder.
	 * After use it, the caller should release the encoder.
	 *
	 * @return The context of the JBig2 encoder.
	 */
	ICodec_Jbig2Encoder*		CreateJbig2Encoder();

	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	/**
	 * Create a Gif encoder.
	 * After using it, the caller should release the encoder.
	 *
	 * @return The context of the GIF encoder.
	 */
	ICodec_GifEncoder*			CreateGifEncoder();

	/**
	 * Create a Bmp encoder.
	 * After using it, the caller should release the encoder.
	 *
	 * @return The context of the BMP encoder.
	 */
	ICodec_BmpEncoder*			CreateBmpEncoder();

     /**
	 * Create a Webp encoder.
	 * After using it, the caller should release the encoder.
	 *
	 * @return The context of the WEBP encoder.
	 */
	ICodec_WebpEncoder*         CreateWebpEncoder(const CFX_DIBSource* pSource);

	//<<<+++OPENSOURCE_END
protected:
	CCodec_ModuleMgr();
	~CCodec_ModuleMgr();

public:
	ICodec_BasicModule*	GetBasicModule() { return m_pBasicModule; }
	ICodec_FaxModule*	GetFaxModule() { return m_pFaxModule; }
	ICodec_JpegModule*	GetJpegModule() { return m_pJpegModule; }
	ICodec_JpxModule*	GetJpxModule() { return m_pJpxModule; }
	ICodec_Jbig2Module*	GetJbig2Module() { return m_pJbig2Module; }
	ICodec_IccModule*	GetIccModule() { return m_pIccModule; }
	ICodec_FlateModule*	GetFlateModule() { return m_pFlateModule; }
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	ICodec_PngModule*	GetPngModule()	{return m_pPngModule;}
	ICodec_GifModule*	GetGifModule()	{return m_pGifModule;}
	ICodec_BmpModule*	GetBmpModule()	{return m_pBmpModule;}
	ICodec_TiffModule*	GetTiffModule()	{return m_pTiffModule;}
    ICodec_WebpModule*	GetWebpModule()	{return m_pWebpModule;}
	//<<<+++OPENSOURCE_END

protected:
	ICodec_BasicModule*	m_pBasicModule;
	ICodec_FaxModule*	m_pFaxModule;
	ICodec_JpegModule*	m_pJpegModule;
	ICodec_JpxModule*	m_pJpxModule;
	ICodec_Jbig2Module*	m_pJbig2Module;
	ICodec_IccModule*	m_pIccModule;
	ICodec_FlateModule*	m_pFlateModule;
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	ICodec_PngModule*	m_pPngModule;
	ICodec_GifModule*	m_pGifModule;
	ICodec_BmpModule*	m_pBmpModule;
	ICodec_TiffModule*	m_pTiffModule;
    ICodec_WebpModule*	m_pWebpModule;
	//<<<+++OPENSOURCE_END
	
};

class ICodec_BasicModule : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_BasicModule() {}
	virtual FX_BOOL	RunLengthEncode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, 
							FX_DWORD& dest_size) = 0;
	virtual FX_BOOL	A85Encode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, 
							FX_DWORD& dest_size) = 0;

	virtual ICodec_ScanlineDecoder*	CreateRunLengthDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, 
														int nComps, int bpc) = 0;
};

/** @brief PDF scanline decoder class. */
class ICodec_ScanlineDecoder : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_ScanlineDecoder() {}

	/** Get the original offset in the source buffer. */
	virtual FX_DWORD	GetSrcOffset() = 0;
	/**
	 * Set the downscale parameters.
	 *
	 * @param[in] dest_width	The destination width.
	 * @param[in] dest_height	The destination height.
	 */
	virtual void		DownScale(int dest_width, int dest_height) = 0;

	/**
	 * Get a scanline.
	 *
	 * @param[in] line			The zero-based row index of the image.
	 * @return The decoded scanline data.
	 */
	virtual FX_LPBYTE	GetScanline(int line) = 0;
	/**
	 * Skip to specified scanline.
	 *
	 * @param[in] line			The zero-based row index to skip to.
	 * @param[in] pPause		The user-supplied pause object.
	 * @return TRUE for to be continued.
	 */
	virtual FX_BOOL		SkipToScanline(int line, IFX_Pause* pPause) = 0;

	/** Get the output width. */
	virtual int			GetWidth() = 0;
	/** Get the output height. */
	virtual int			GetHeight() = 0;
	/** Get the number of components. */
	virtual int			CountComps() = 0;
	/** Get the bits per component. */
	virtual int			GetBPC() = 0;
	/** Check whether the color has been transformed. */
	virtual FX_BOOL		IsColorTransformed() = 0;
	/** Clear the cached image data. */
	virtual void		ClearImageData() = 0;
};

class ICodec_FlateModule : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_FlateModule() {}
	virtual ICodec_ScanlineDecoder*	CreateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, 
				int nComps, int bpc, int predictor, int Colors, int BitsPerComponent, int Columns) = 0;

	virtual FX_DWORD	FlateOrLZWDecode(FX_BOOL bLZW, const FX_BYTE* src_buf, FX_DWORD src_size, FX_BOOL bEarlyChange, 
				 int predictor, int Colors, int BitsPerComponent, int Columns,
				 FX_DWORD estimated_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size) = 0;

	virtual FX_BOOL		Encode(const FX_BYTE* src_buf, FX_DWORD src_size, 
				int predictor, int Colors, int BitsPerComponent, int Columns,
				FX_LPBYTE& dest_buf, FX_DWORD& dest_size) = 0;

	virtual FX_BOOL		Encode(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size) = 0;

	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	// Progressive Encode
	virtual FX_LPVOID		DeflateInit() = 0;
	virtual void			DeflateInput(FX_LPVOID context, FX_LPCBYTE src_buf, FX_DWORD src_size) = 0;
	virtual int				DeflateOutput(FX_LPVOID context, FX_LPBYTE dest_buf, FX_UINT32* dest_size, FX_BOOL bLast) = 0;
	virtual int				DeflateGetAvailOut(FX_LPVOID context) = 0;
	virtual void			DeflateEnd(FX_LPVOID context) = 0;
	//<<<+++OPENSOURCE_END
};

/** @brief FAX module, providing CCITT fax decoding and encoding */
class ICodec_FaxModule : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_FaxModule() {}
	/** Get the scanline decoder. See detail in pdf reference CCITTFaxDecode Filter.
	 *
	 * @param[in] src_buf	The input source CCITT-encoded buffer(both group3 and group4).
	 * @param[in] src_siz	The size in bytes of the buffer.
	 * @param[in] width		The width of the image in pixels. effected in Columns is 0.
	 * @param[in] height	The height of the image in scan lines. effected in Rows is 0.
	 * @param[in] K			A code identifying the encoding scheme used: 
	 *						< 0 Pure two-dimensional encoding (Group 4)
	 *						= 0 Pure one-dimensional encoding (Group 3, 1-D) 
	 *						> 0 Mixed one- and two-dimensional encoding (Group 3, 2-D), 
	 *						    in which a line encoded one-dimensionally can be followed 
	 *						    by at most K ? 1 lines encoded two-dimensionally 
	 *						The filter distinguishes among negative, zero, and positive values of 
	 *						K to determine how to interpret the encoded data; however, it does 
	 *						not distinguish between different positive K values.
	 * @param[in] EndOfLine	A flag indicating whether end-of-line bit patterns are required to be 
	 *						present in the encoding.
	 * @param[in] EncodedByteAlign	A flag indicating whether the filter expects extra 0 bits before each 
	 *								encoded line so that the line begins on a byte boundary.
	 * @param[in] BlackIs1	A flag indicating whether 1 bits are to be interpreted as black pixels 
	 *						and 0 bits as white pixels
	 * @param[in] Columns	The width of the image in pixels, be described in pdf reference.
	 * @param[in] Rows		The height of the image in scan lines, be described in pdf reference.
	 * @return The scanline decoder.
	 */
	virtual ICodec_ScanlineDecoder*	CreateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, 
				int K, FX_BOOL EndOfLine, FX_BOOL EncodedByteAlign, FX_BOOL BlackIs1, int Columns, int Rows) = 0;
	
	/**
	 * Encode an image, only CCITT Group4 encoded now.
	 *
	 * @param[in] src_buf			The input raw bi-level image buffer.
	 * @param[in] width				The with of the image.
	 * @param[in] height			The height of the image.
	 * @param[in] pitch				The row bytes. 
	 * @param[out] dest_buf			It receives the encoded data. The caller must release the data by FX_Free.
	 * @param[out] dest_size		It receives the size of the encoded data.
	 * @return Non-zero means success, otherwise failure.
	 */
	virtual FX_BOOL		Encode(FX_LPCBYTE src_buf, int width, int height, int pitch, 
							FX_LPBYTE& dest_buf, FX_DWORD& dest_size) = 0;
};

/** @brief JPEG module, providing JPEG decoding & encoding. */
class ICodec_JpegModule : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_JpegModule() {}

	/** Set external Jpeg codec provider */
	virtual void		SetPovider(IFX_JpegProvider* pJP) = 0;

	/** Get the scanline decoder. */
	virtual ICodec_ScanlineDecoder*	CreateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, 
					int width, int height, int nComps, FX_BOOL ColorTransform) = 0;

	/**
	 * Load information from a JPEG-encoded buffer.
	 *
	 * @param[in] src_buf					The input source JPEG-encoded buffer.
	 * @param[in] src_size					The size in bytes of the buffer.
	 * @param[out] width					It receives the image width.
	 * @param[out] height					It receives the image height.
	 * @param[out] num_components			It receives the number of components.
	 * @param[out] bits_per_components		It receives bits per component.
	 * @param[out] color_transform			It receives whether need to transform color.
	 * @param[out] icc_buf_ptr				It receives the icc profile data if it exist. The caller should FX_Free it after use it.
	 * @param[out] icc_length				It receives the icc profile stream size if it exist.
	 * @param[Out] pAttribute			The attribute information of bitmap.
	 * @return Non-zero means success, otherwise failure.
	 */
#ifdef _FXM_OPENSOURCE_
	//<<<+++OPENSOURCE_BEGIN LIC==GOOGLE
	virtual FX_BOOL		LoadInfo(FX_LPCBYTE src_buf, FX_DWORD src_size, int& width, int& height,
					int& num_components, int& bits_per_components, FX_BOOL& color_transform,
					FX_LPBYTE* icc_buf_ptr = NULL, FX_DWORD* icc_length = NULL) = 0;
	//<<<+++OPENSOURCE_END
#else
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	virtual FX_BOOL		LoadInfo(FX_LPCBYTE src_buf, FX_DWORD src_size, int& width, int& height,
				   int& num_components, int& bits_per_components, FX_BOOL& color_transform,
				   FX_LPBYTE* icc_buf_ptr = NULL, FX_DWORD* icc_length = NULL, CFX_DIBAttribute* pAttribute = NULL) = 0;
	//<<<+++OPENSOURCE_END
#endif

	/**
	 * Encode an image. 
	 * If the encoded CMYK stream be embedded to PDF, the application must 
	 * set an image dictionaries option entry, /Decode [1 0 1 0 1 0 1 0], first. 
	 *
	 * @param[in] pSource				The source image to be encoded.
	 * @param[out] dest_buf				It receives the encoded JPEG data.
	 * @param[out] dest_size			It receives the size of the encoded JPEG data. The caller must release the data by FX_Free.
	 * @param[in]  quality				The compressed quality of destination jpeg image(0~100)	
	 * @param[in] icc_buf				The icc profile will embeded to the compressed stream.
	 * @param[in] icc_length			The icc profile stream size.
	 * @param[in] pAttribute			The attribute information of bitmap.
	 * @return Non-zero means success, otherwise failure.
	 */
#ifdef _FXM_OPENSOURCE_
	//<<<+++OPENSOURCE_BEGIN LIC==GOOGLE
	virtual FX_BOOL		Encode(const class CFX_DIBSource* pSource, FX_LPBYTE& dest_buf, FX_STRSIZE& dest_size, int quality = 75,
					FX_LPCBYTE icc_buf = NULL, FX_DWORD icc_length = 0) = 0;
	//<<<+++OPENSOURCE_END
#else
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	virtual FX_BOOL		Encode(const class CFX_DIBSource* pSource, FX_LPBYTE& dest_buf, FX_STRSIZE& dest_size, int quality = 75,
					FX_LPCBYTE icc_buf = NULL, FX_DWORD icc_length = 0, CFX_DIBAttribute* pAttribute = NULL) = 0;
	//<<<+++OPENSOURCE_END
#endif

	/** 
	 * Start a progressive JPEG decoding process.
	 *
	 * @return A context pointer.
	 */
	virtual void*		Start() = 0;

	/** 
	 * Finish a progressive JPEG decoding process.
	 *
	 * @param[in] pContext				The context pointer.
	 */
	virtual void		Finish(void* pContext) = 0;

	/** 
	 * Provide input to the decoder. This function can be called multiple times, everytime with some new input.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[in] src_buf				Input buffer.
	 * @param[in] src_size				Size of input data.
	 */
	virtual void		Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size) = 0;

	/** 
	 * Reader the header of the JPEG stream so we can get basic information about the picture.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[out] width				Receiving image width.
	 * @param[out] height				Receiving image height.
	 * @param[out] nComps				Receiving number of components.
	 * @param[out] pAttribute		The attribute information of bitmap.
	 * @return 0 for success, 1 for error, 2 for suspended (need more input).
	 */
#ifdef _FXM_OPENSOURCE_
	//<<<+++OPENSOURCE_BEGIN LIC==GOOGLE
	virtual int			ReadHeader(void* pContext, int* width, int* height, int* nComps) = 0;
	//<<<+++OPENSOURCE_END
#else
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	virtual int			ReadHeader(void* pContext, int* width, int* height, int* nComps, CFX_DIBAttribute* pAttribute = NULL) = 0;
	//<<<+++OPENSOURCE_END
#endif
	
	/** 
	 * Start scanline decoding, and specify down scale. ReadHeader() must be successful before this function is called.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[in] down_scale			Down scale factore, can be 1 (no down scale), 2, 4, or 8.
	 *									If the picture is very big, then down scaling can be very efficient.
	 *									After down-scaling, output width and height will be reduced:
	 *									output_width = (original_width + down_scale - 1) / down_scale
	 *									output_height = (original_height + down_scale - 1) / down_scale
	 * @return TRUE for success, FALSE for error or suspended (need more data)
	 */
	virtual int			StartScanline(void* pContext, int down_scale) = 0;
	
	/** 
	 * Read one scanline from the decoder. StartScanline() must be called first.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[in] dest_buf				Pointer to the scanline buffer. The caller must ensure the buffer 
	 *									is big enough to hold the whole scanline.
	 * @return TRUE for success, FALSE for error or suspended (need more data)
	 */
	virtual FX_BOOL		ReadScanline(void* pContext, FX_LPBYTE dest_buf) = 0;
	
	/** 
	 * Get number of bytes available in the input buffer.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[out] avail_buf_ptr		It receives the avail buf pointer, 
	 *									do not free it, it's partial src_buf of the caller Input.
	 * @return Number of bytes left in the input buffer.
	 */
	virtual FX_DWORD	GetAvailInput(void* pContext, FX_LPBYTE* avail_buf_ptr = NULL) = 0;
};

/** @brief JPX module, providing JPEG2000 decoding. */
class ICodec_JpxModule : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_JpxModule() {}
	/**
	 * Create a JPX decoder.
	 *
	 * @param[in] src_buf			The source JPX encoded data.
	 * @param[in] src_size			The size of the encoded data.
	 * @return The context of the JPX decoder.
	 */
	virtual FX_LPVOID 	CreateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_BOOL useColorSpace = FALSE) = 0;
	/**
	 * Get the image information.
	 * if codestream_nComps > 3 and output_nComps >= 3, such as codestream_nComps == 4, 
	 * and if output_nComps == 3, then the image should be in FXDIB_RGB32 format;
	 * if output_nComps == 4, then the image should be in FXDIB_CMYK format.
	 * 
	 *
	 * @param[in] ctx					The JPX decoder context.
	 * @param[out] width				It receives the image width.
	 * @param[out] height				It receives the image height.
	 * @param[out] codestream_nComps	It receives the number of components in the codestream.
	 * @param[out] output_nComps		It receives the number of output channels.
	 * @param[Out] pAttribute		The attribute information of bitmap.
	 */
#ifdef _FXM_OPENSOURCE_
	//<<<+++OPENSOURCE_BEGIN LIC==GOOGLE
	virtual void		GetImageInfo(FX_LPVOID ctx, FX_DWORD& width, FX_DWORD& height, 
							FX_DWORD& codestream_nComps, FX_DWORD& output_nComps) = 0;
	//<<<+++OPENSOURCE_END
#else
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	virtual void		GetImageInfo(FX_LPVOID ctx, FX_DWORD& width, FX_DWORD& height, 
							FX_DWORD& codestream_nComps, FX_DWORD& output_nComps, CFX_DIBAttribute* pAttribute = NULL) = 0;

	virtual FX_BOOL     Start(void* ctx, FX_LPBYTE dest_data, int pitch, FX_BOOL bTranslateColor, FX_LPBYTE offsets) = 0;
	virtual FX_ProgressiveStatus     Continue(void* ctx, IFX_Pause* pause) = 0;
	//<<<+++OPENSOURCE_END
#endif

	/**
	 * Decode the image.
	 *
	 * @param[in] ctx					The JPX decoder context.
	 * @param[in, out] dest_data		It receives the decoded data.
	 * @param[in] pitch					The row pitch of the provided destination data.
	 * @param[in] bTranslateColor		Whether need the JPX decoder to translate color.
	 * @param[in] offsets				The offsets in the provided destination data of each component of the image.
	 */
	virtual FX_BOOL		Decode(FX_LPVOID ctx, FX_LPBYTE dest_data, int pitch, 
							FX_BOOL bTranslateColor, FX_LPBYTE offsets) = 0;
	/**
	 * Destroy a JPX decoder.
	 *
	 * @param[in] ctx				The JPX decoder context.
	 */
	virtual void		DestroyDecoder(FX_LPVOID ctx) = 0;
};

//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
/** @brief PNG file decoder class. */
class ICodec_PngDecoder : public CFX_Object
{
public:
	typedef enum{
		PNG_Gray = 0,			///< 1,2,4 or 8 bits per component gray image
		PNG_Color = 2,			///< 8 or 16 bits per component true color image
		PNG_Color_Palette = 3,	///< 1,2,4 or 8 bits per component index color image from palette
		PNG_Gray_Alpha = 4,		///< 8 or 16 bits per component gray image with alpha component
		PNG_Color_Alpha = 6		///< 8 or 16 bits per component true color image with alpha component
	} PNG_Color_Type;

	typedef enum	///< set filler(usually alpha) to the png file, for support transparency .
	{
		PNG_Filler_Before = 0,	///< 0xARGB, 0xABGR or 0xAGray
		PNG_Filler_After = 1	///< 0xRGBA, 0xBGRA or 0xGrayA
	} PNG_Filler_Type;

	/** The destructor. */
	virtual ~ICodec_PngDecoder() {}

	/**
	 * Get a scanline.	
	 * You should supply the scanline buffer with size(>= GetPitch() below).
	 * If you decode pass by pass and line by line, will the fastest decoder.
	 *
	 * @param[in] pass			The zero-based pass index of the png image.
	 * @param[in] line			The zero-based row index of the image.
	 * @param[in,out] pScanline The source scanline should contain the same line data 
	 *							in the previous pass.  
	 * @return The decoded scanline data.
	 */
	virtual FX_BOOL		GetScanline(int pass, int line, FX_LPBYTE pScanline) = 0;
	
	/** The decoder will decode whole image one time if you have enough memory. 
	 *	Do not free the returned buffer.
	 *	The image size: GetPitch() * GetHeight().
	 */
	virtual FX_LPBYTE	GetEntireImage() = 0;

	/**	Get the number of png image pass, when you GetScanline with pass. */
	virtual FX_INT32	GetNumberPasses() = 0;
	/** Get the output width. */
	virtual int			GetWidth() = 0;
	/** Get the output height. */
	virtual int			GetHeight() = 0;
	/** Get the number of components. */
	virtual int			CountComps() = 0;
	/** Get the bits per component. */
	virtual int			GetBPC() = 0;
	/** Get the row bytes of original scanline, may not equal to CFX_DIBitmap::GetPitch() */
	virtual FX_DWORD	GetPitch() = 0;

	/** Get the color type of png. */
	virtual PNG_Color_Type	GetColorType() = 0;
	
	/** Note that screen gamma is the display_exponent, which includes
     *	the CRT_exponent and any correction for viewing conditions. If
	 *	you know the display gamma, set it, otherwise, set 2.2 for PC, 
	 *	1.7 for Mac systems. Recommended do this method.
	 */
	virtual void		SetScreenGamma(double dGamma = 2.2) = 0;

	/** Tell the decoder to strip 16 bpc down to 8 bpc color. */
	virtual void		SetStrip_16_to_8() = 0;

	/** Strip alpha bytes from the input data without combining with the
     *	background (not recommended).
     */
	virtual void		SetStripAlpha() = 0;

	/** Expand gray scale images to the full 8 bits from 1, 2, or 4 bits/pixel, valid when color type is gray. */
	virtual void		SetExpandGray_1_2_4_to_8() = 0;

	/** Expand paletted colors into true RGB triplets, valid when color type is color palette index. */
	virtual void		SetPalette2Rgb() = 0;

	/** Expand 8 or 16 bits gray(A) to rgb(A), do 1, 2, or 4 bits pixel expand to full 8 bits first. */
	virtual void		SetGray2Rgb() = 0;

	/** Flip the RGB pixels to BGR (or RGBA to BGRA) */
	virtual void		SetRGB2BGR() = 0;

	/**	Swap the RGBA or GrayA data to ARGB or AGray, or if you SetRGB2BGR 
	 *	above, the decoder will do set BGRA to ABGR.
	 */
	virtual void		SetSwapAlpha() = 0;
	
	/** Swap bytes of 16 bit files to little endian byte first */
	virtual void		SetSwap() = 0;
	
	/** Add filler (or alpha) byte (before/after each RGB triplet), 0xff default value. */
	virtual void		SetFiller(PNG_Filler_Type fill_type = PNG_Filler_After, FX_DWORD fill_value = 0xff) = 0;

	/** Expand paletted or RGB images with transparency to full alpha channels
	 *	so the data will be available as RGBA quartets. Valid only when the file
	 *	has the transparency data chunk(tRNS).
	 */
	virtual void		SetTrans2Alpha() = 0;

	/** color order: 0xbbggrrGrayGray. for color image use bbggrr, gray image use GrayGray. */
	virtual void		SetBackground(FX_DWORD bgColor) = 0;

	/** REQUIRED if you are expecting the decoder to decode the image as you
	 *	set above. Do this method before get data(GetScanline and GetEntireImage).
	 *	NOTE: Only do once.
	 *
	 *	NOTE: This method may change the Pitch, bpc, number components and color type. If you do 
	 *	this method, you must re-get the four methods for final information.
	 *
	 *	@return Non-zero means success, otherwise failure.
	 */
	virtual FX_BOOL		UpdatePngReadInfo() = 0;
};

/** @brief PNG module, providing PNG decoding. */
class ICodec_PngModule : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_PngModule() {} 
	/**
	 *	Get the png decoder from a file, ANSIC version.
	 *
	 *	@param[in]	file_name			The input image file name.
	 *  @param[Out] pAttribute		The attribute information of bitmap.
	 *	@return Non-zero means success, otherwise failure.
	 */
	virtual ICodec_PngDecoder*	CreateDecoder(FX_LPCSTR file_name, CFX_DIBAttribute* pAttribute = NULL) = 0;

	/**
	 *	Get the png decoder from a file, Unicode version.
	 *
	 *	@param[in]	file_name			The input image file name.
	 *  @param[Out] pAttribute		The attribute information of bitmap.
	 *	@return Non-zero means success, otherwise failure.
	 */
	virtual ICodec_PngDecoder*	CreateDecoder(FX_LPCWSTR file_name, CFX_DIBAttribute* pAttribute = NULL) = 0;

	/**
	 *	Get the png decoder from memory block.
	 *
	 *	@param[in] src_buf					The input source PNG-encoded buffer.
	 *	@param[in] src_size					The size in bytes of the buffer.
	 *  @param[Out] pAttribute			The attribute information of bitmap.
	 *	@return Non-zero means success, otherwise failure.
	 */
	virtual ICodec_PngDecoder*	CreateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_DIBAttribute* pAttribute = NULL) = 0;

	/**
	 *	Get the png decoder from a custom file.
	 *
	 *	@param[in] pFile					The stream access interface.
	 *	@param[in] bOwnedFileRead			Whether ICodec_PngModule takes ownership of the file read structure (by calling IFX_FileRead::Release() when parser cleans up)
	 *  @param[Out] pAttribute			The attribute information of bitmap.
	 *	@return Non-zero means success, otherwise failure.
	 */
	virtual ICodec_PngDecoder*	CreateDecoder(IFX_FileRead* pFile, FX_BOOL bOwnedFileRead = TRUE, CFX_DIBAttribute* pAttribute = NULL) = 0;
	
	/**
	 * Encode an image to a file, ANSIC version. 
	 *
	 * @param[in] pSource				The source image to be encoded.
	 * @param[in] file_name				Encoded PNG file save position.
	 * @param[in] bInterlace			Whether the PNG file be interlace(7 passes)	
	 * @param[in] pAttribute			The attribute information of bitmap.
	 * @return Non-zero means success, otherwise failure.
	 */
	virtual FX_BOOL		Encode(const CFX_DIBSource* pSource, FX_LPCSTR file_name, FX_BOOL bInterlace = FALSE, CFX_DIBAttribute* pAttribute = NULL) = 0;

	/**
	 * Encode an image to a file, Unicode version. 
	 *
	 * @param[in] pSource				The source image to be encoded.
	 * @param[in] file_name				Encoded PNG file save position.
	 * @param[in] bInterlace			Whether the PNG file be interlace(7 passes)	
	 * @param[in] pAttribute			The attribute information of bitmap.
	 * @return Non-zero means success, otherwise failure.
	 */
	virtual FX_BOOL		Encode(const CFX_DIBSource* pSource, FX_LPCWSTR file_name, FX_BOOL bInterlace = FALSE, CFX_DIBAttribute* pAttribute = NULL) = 0;

	/**
	 * Encode an image to a memory block, the return buffer must be free by FX_Free. 
	 *
	 * @param[in] pSource				The source image to be encoded.
	 * @param[out] dest_buf				It receives the encoded PNG data.
	 * @param[out] dest_size			It receives the size of the encoded PNG data.
	 * @param[in] bInterlace			Whether the PNG file be interlace(7 passes)	
	 * @param[in] pAttribute			The attribute information of bitmap.
	 * @return Non-zero means success, otherwise failure.
	 */
	virtual FX_BOOL		Encode(const CFX_DIBSource* pSource, FX_LPBYTE& dest_buf, FX_DWORD& dest_size, FX_BOOL bInterlace = FALSE, CFX_DIBAttribute* pAttribute = NULL) = 0;

	/**
	 * Encode an image to a custom file.
	 *
	 * @param[in] pSource				The source image to be encoded.
	 * @param[in] pFile					The stream access interface.
	 * @param[in] bOwnedFileWrite		Whether ICodec_PngModule takes ownership of the file read structure (by calling IFX_FileWrite::Release() when parser cleans up)
	 * @param[in] bInterlace			Whether the PNG file be interlace(7 passes)	
	 * @param[in] pAttribute			The attribute information of bitmap.
	 * @return Non-zero means success, otherwise failure.
	 */
	virtual FX_BOOL		Encode(const CFX_DIBSource* pSource, IFX_FileWrite* pFile, FX_BOOL bInterlace = FALSE, FX_BOOL bOwnedFileWrite = TRUE, CFX_DIBAttribute* pAttribute = NULL) = 0;

	/** 
	 *	Get the png module last error code
	 *
	 *	@return Error string
	 */
	virtual FX_LPCSTR		GetLastError() = 0;

	/** 
	 *	Start a progressive PNG decoding process.
	 *	User should implement three callback function below.
	 *
	 *	@param[in] pModule				The consumer application pointer.
	 *	@return A context pointer.
	 */
	virtual void*		Start(void* pModule) = 0;

	/** 
	 * Finish a progressive PNG decoding process.
	 *
	 * @param[in] pContext				The context pointer.
	 */
	virtual void		Finish(void* pContext) = 0;

	/** 
	 *	Provide input to the decoder. This function can be called multiple times, every time with some new input.
	 *	The decoder start decoding the stream immediately when get input, and trigger the callback below when 
	 *	the input enough.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[in] src_buf				Input buffer.
	 * @param[in] src_size				Size of input data.
	 * @param[out] pAttribute		The attribute information of bitmap.
	 * @return Non-zero means success, otherwise failure. FALSE for decode error, detail see GetLastError()
	 */
	virtual FX_BOOL		Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_DIBAttribute* pAttribute = NULL) = 0;

	/** 
	 *	Callback function
	 *	Called after header data fully read
	 *
	 *	@param[in] pModule				The consumer application pointer. convert to itself type pointer do any operation
	 *	@param[in] width				The return image width
	 *	@param[in] height				The return image height
	 *	@param[in] bpc					The return image bits per component, any other bpc be transform to 8bpc now.
	 *	@param[in] pass					The return image pass number 
	 *	@param[out] color_type			The image color type defined same as the enum PNG_Color_Type in ICodec_PngDecoder,
	 *									user can modify and the decoder use the result
	 *	@param[out] gamma				The image gamma for correct, set 2.2 for PC, 1.7 for Mac systems.
	 *	@return Non-zero means success, otherwise failure. 
	 *			If you return FALSE, the Input(...) will return FALSE with decode error. 
	 */
	FX_BOOL				(*ReadHeaderCallback)(void* pModule, int width, int height, int bpc, int pass, int* color_type, double* gamma);

	/** 
	 *	Callback function
	 *	Ask user to provide buffer for holding decoded stream.
	 *	Called after each scanline is decoded.
	 *
	 *	@param[in] pModule				The consumer application pointer. convert to itself type pointer do any operation
	 *	@param[in] line					Indicate the image zero-based row number the user should provided
	 *	@param[out] src_buf				The scanline buffer user provided, and the decoder will set the decoded data in it.
	 *	@return Non-zero means success, otherwise failure.
	 *			If you return FALSE, the Input(...) will return FALSE with decode error.
	 */
	FX_BOOL				(*AskScanlineBufCallback)(void* pModule, int line, FX_LPBYTE& src_buf);

	/** 
	 *	Callback function
	 *	Notify user the current decoded scanline has been filled to the buffer.
	 *	Called after each scanline is decoded. 
	 *
	 *	@param[in] pModule				The consumer application pointer. convert to itself type pointer do any operation
	 *	@param[in] pass					Indicate the image current decoded zero-based pass number
	 *	@param[in] line					Indicate the image current decoded zero-based row number
	 */
	void				(*FillScanlineBufCompletedCallback)(void* pModule, int pass, int line);
};

/** @brief GIF module, providing GIF decoding. */
class ICodec_GifModule : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_GifModule() {}
	/** 
	 *	Get the gif module last error code
	 *
	 *	@return Error string
	 */
	virtual FX_LPCSTR	GetLastError() = 0;

	/** 
	 *	Start a progressive GIF decoding process.
	 *	User should implement the four callback function below.
	 *
	 *	@param[in] pModule				The consumer application pointer.
	 *	@return A context pointer.
	 */
	virtual void*		Start(void* pModule) = 0;

	/** 
	 * Finish a progressive GIF decoding process.
	 *
	 * @param[in] pContext				The context pointer.
	 */
	virtual void		Finish(void* pContext) = 0;

	/** 
	 * Get number of bytes available in the input buffer.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[out] avail_buf_ptr		It receives the avail buf pointer, 
	 *									do not free it, it's partial src_buf of the caller Input.
	 * @return Number of bytes left in the input buffer.
	 */
	virtual FX_DWORD	GetAvailInput(void* pContext, FX_LPBYTE* avail_buf_ptr = NULL) = 0;

	/** 
	 *	Provide input to the decoder. This function can be called multiple times, every time with some new input.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[in] src_buf				Input buffer.
	 * @param[in] src_size				Size of input data.
	 */
	virtual void		Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size) = 0;

	/** 
	 * Reader the header of the GIF stream so we can get basic information about the picture.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[out] width				Receiving image width.
	 * @param[out] height				Receiving image height.
	 * @param[out] pal_num				Receiving number of global palette entries.
	 * @param[out] pal_pp				Receiving pointer of global palette, do not free it. 
	 *									Each palette entry just like this: struct{FXBYTE r,g,b;};
	 * @param[out] bg_index				Receiving background index of palette, invalid in opaque image.
	 * @param[out] pAttribute			The attribute information of bitmap.
	 * 
	 * @return 1 for success, 0 for error, 2 for suspended (need more input).
	 */
	virtual FX_INT32	ReadHeader(void* pContext, int* width, int* height, 
									int* pal_num, void** pal_pp, int* bg_index, CFX_DIBAttribute* pAttribute = NULL) = 0;

	/** 
	 * Load frame information of the GIF stream so we can get information about the each picture.
	 * Will traversal the whole image, and will trigger the callback RecordCurrentPositionCallback
	 * and AskLocalPaletteBufCallback.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[out] frame_num			Receiving image frame number.
	 * @return 1 for success, 0 for error, 2 for suspended (need more input).
	 */
	virtual FX_INT32	LoadFrameInfo(void* pContext, int* frame_num) = 0;


	/** 
	 *	Callback function
	 *	Called when reach each frame of multi-frame image, you must supply the correct position information, 
	 *	otherwise, you can not Load Frame correctly
	 *
	 *	@param[in] pModule		The consumer application pointer. convert to itself type pointer do any operation
	 *	@param[out] cur_pos		The offset position of consumer last time input buffer to the decoder.
	 *							cur_pos = your total input size - GetAvailInput()
	 */
	void				(*RecordCurrentPositionCallback)(void* pModule, FX_DWORD& cur_pos);

	/** 
	 *	Callback function
	 *	Called when reach each frame of multi-frame image and the frame image has the local palette, 
	 *	you can according to the frame_num(zero-based) to decide whether FX_Alloc the size(pal_size) of buffer 
	 *	to the decoder. if you do not supply it, just return NULL, and when you LoadFrame of the same frame,
	 *	you must use your own palette or global palette.
	 *
	 *	@param[in] pModule		The consumer application pointer. convert to itself type pointer do any operation
	 *	@param[in] frame_num	The current frame has itself palette
	 *	@param[in] pal_size		The size decoder need. Use FX_Alloc, and takeover by the decoder.
	 *  @return the Palette buffer the decoder need.
	 */
	FX_LPBYTE			(*AskLocalPaletteBufCallback)(void* pModule, FX_INT32 frame_num, FX_INT32 pal_size);

	/** 
	 * Load the zero-based frame image of the GIF stream.
	 * Will trigger the callback InputRecordPositionBufCallback and ReadScanlineCallback for some information.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[out] frame_num			The zero-based frame image you want to load.
	 * @param[out] pAttribute			The attribute information of bitmap.
	 * @return 1 for success, 0 for error, 2 for suspended (need more input).
	 */
	virtual FX_INT32	LoadFrame(void* pContext, int frame_num, CFX_DIBAttribute* pAttribute = NULL) = 0;

	/** 
	 *	Callback function
	 *	Called when you LoadFrame, and tell you to input the rcd_pos data to the decoder
	 *	and give you some information of the corresponding image.
	 *
	 *	@param[in] pModule		The consumer application pointer. convert to itself type pointer do any operation
	 *	@param[in] rcd_pos		The offset position of the stream you should provide to the decoder.
	 *							You must Input(pContext,src_buf_start + rcd_pos,src_size)
	 *	@param[in] img_rc		The image rect in the range of header return width and height.
	 *	@param[in] pal_num		If has the corresponding local palette, will return you the palette number,
	 *							otherwise, return zero, and you should use the global palette.
	 *	@param[in] pal_ptr		If NULL, you must use your own palette or global palette with size pal_num.
	 *	@param[in] delay_time	The return frame image control information, the delay time of previous frame.
	 *							Specifies the number of hundredths (1/100) of a second to wait before continuing
	 *							with the processing of the Data Stream. The clock starts ticking immediately
	 *							after the graphic is rendered.     
	 *	@param[in] user_input	The return frame image control information, if user input(some...) swap to this frame.
	 *	@param[in] trans_index	-1 for opaque image, 0-255 for index of palette transparent.
	 *	@param[in] disposal_method	The return frame image control information
	 *				Value:			0 -   No disposal specified. The decoder is not required to take any action.
	 *								1 -   Do not dispose. The graphic is to be left in place.
	 *								2 -   Restore to background color. The area used by the graphic must be 
	 *									  restored to the background color.
	 *								3 -   Restore to previous. The decoder is required to restore the area
	 *									  overwritten by the graphic with what was there prior to rendering
	 *									  the graphic.
	 * @param[in] interlace		Return TRUE for interlace frame image with 4 passes, else only 1 pass.
	 */
	FX_BOOL				(*InputRecordPositionBufCallback)(void* pModule, FX_DWORD rcd_pos, const FX_RECT& img_rc,
														FX_INT32 pal_num, void* pal_ptr,
														FX_INT32 delay_time, FX_BOOL user_input,
														FX_INT32 trans_index, FX_INT32 disposal_method, FX_BOOL interlace);
	/** 
	 *	Callback function
	 *	This function will be called multiple times, every time with a new scanline output.
	 *
	 *	@param[in] pModule		The consumer application pointer. convert to itself type pointer do any operation.
	 *	@param[in] row_num		The zero-based scanline number be output.
	 *	@param[in] row_buf		The buffer of the scanline, always 1 component 8 bpp index buffer.
	 */
	void				(*ReadScanlineCallback)(void* pModule, FX_INT32 row_num, FX_LPBYTE row_buf);
};

/** @brief BMP module, providing BMP decoding. */
class ICodec_BmpModule : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_BmpModule() {}
	/** 
	 *	Get the bmp module last error code
	 *
	 *	@return Error string
	 */
	virtual FX_LPCSTR	GetLastError() = 0;

	/** 
	 *	Start a progressive BMP decoding process.
	 *	User should implement the two callback function below.
	 *
	 *	@param[in] pModule				The consumer application pointer.
	 *	@return A context pointer.
	 */
	virtual void*		Start(void* pModule) = 0;

	/** 
	 * Finish a progressive BMP decoding process.
	 *
	 * @param[in] pContext				The context pointer.
	 */
	virtual void		Finish(void* pContext) = 0;

	/** 
	 * Get number of bytes available in the input buffer.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[out] avail_buf_ptr		It receives the avail buf pointer, 
	 *									do not free it, it's partial src_buf of the caller Input.
	 * @return Number of bytes left in the input buffer.
	 */
	virtual FX_DWORD	GetAvailInput(void* pContext, FX_LPBYTE* avail_buf_ptr = NULL) = 0;

	/** 
	 *	Provide input to the decoder. This function can be called multiple times, every time with some new input.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[in] src_buf				Input buffer.
	 * @param[in] src_size				Size of input data.
	 */
	virtual void		Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size) = 0;

	/** 
	 * Reader the header of the BMP stream so we can get basic information about the picture.
	 *
	 * @param[in] pContext				The context pointer.
	 * @param[out] width				Receiving image width.
	 * @param[out] height				Receiving image height.
	 * @param[out] tb_flag				Receiving image top --> bottom order flag. FALSE for bottom up
	 * @param[out] components			Receiving image component numbers
	 *									Value:	1	palette image, always 1 component 8 bpp index buffer.
	 *											3	rgb image
	 *											4	rgb32 image
	 * @param[out] pal_num				Receiving number of palette entries. valid in palette image.
	 * @param[out] pal_pp				Receiving pointer of palette, do not free it. 
	 *									Each palette entry just like this: 0xaarrggbb
	 * @param[Out] pAttribute			The attribute information of bitmap.
	 * @return 1 for success, 0 for error, 2 for suspended (need more input).
	 */
	virtual FX_INT32	ReadHeader(void* pContext, FX_INT32* width, FX_INT32* height, FX_BOOL* tb_flag, FX_INT32* components,
									int* pal_num, FX_DWORD** pal_pp, CFX_DIBAttribute* pAttribute = NULL) = 0;

	/** 
	 * Start scanline decoding.
	 * Will trigger the callback InputImagePositionBufCallback and ReadScanlineCallback for some information.
	 *
	 * @param[in] pContext				The context pointer.
	 * @return 1 for success, 0 for error, 2 for suspended (need more input).
	 */
	virtual FX_INT32	LoadImage(void* pContext) = 0;

	/** 
	 *	Callback function
	 *	Called when you LoadImage, and tell you to input the rcd_pos data to the decoder, you should check
	 *	the position not out of range.
	 *
	 *	@param[in] pModule		The consumer application pointer. convert to itself type pointer do any operation
	 *	@param[in] rcd_pos		The offset position of the stream you should provide to the decoder.
	 *							Make sure rcd_pos in the range of you own stream size, otherwise, just return false.
	 */
	FX_BOOL				(*InputImagePositionBufCallback)(void* pModule, FX_DWORD rcd_pos);

	/** 
	 *	Callback function
	 *	This function will be called multiple times, every time with a new scanline output.
	 *
	 *	@param[in] pModule		The consumer application pointer. convert to itself type pointer do any operation.
	 *	@param[in] row_num		The zero-based scanline number be output.
	 *	@param[in] row_buf		The buffer of the scanline.
	 */
	void				(*ReadScanlineCallback)(void* pModule, FX_INT32 row_num, FX_LPBYTE row_buf);
};

/** @brief Tiff module, providing Tiff decoding. */
class ICodec_TiffModule : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_TiffModule() {}
	/**
	 * Create a Tiff decoder.
	 *
	 * @param[in] file_ptr			The source TIFF encoded data reading interface.
	 * @return The context of the TIFF decoder.
	 */
	virtual FX_LPVOID 	CreateDecoder(IFX_FileRead* file_ptr) = 0;
	
	/**
	 * Get the frame number of a Tiff codestream.
	 *
	 * @param[in] ctx				The TIFF decoder context.
	 * @param[out] frames			The number of frame.
	 */
	virtual void		GetFrames(FX_LPVOID ctx, FX_INT32& frames) = 0;

	/**
	 * Get the frame information.
	 * This function can be called multiple times, every time with different frame number input.
	 * According to the comps and bpc, application could do inverse quantization(Argb -> 1bppRgb/8bppRgb).
	 *
	 * @param[in] ctx					The TIFF decoder context.
	 * @param[in] frame					The zero-based frame number.
	 * @param[out] width				It receives the frame width.
	 * @param[out] height				It receives the frame height.
	 * @param[out] comps				It receives the number of components in the codestream.
	 * @param[out] bpc					It receives the bits per component.
	 * @param[out] pAttribute			The attribute information of bitmap.
	 * @return TRUE for success, FALSE for fail.
	 */
	virtual FX_BOOL		LoadFrameInfo(FX_LPVOID ctx, FX_INT32 frame, FX_DWORD& width, FX_DWORD& height, FX_DWORD& comps, FX_DWORD& bpc, CFX_DIBAttribute* pAttribute = NULL) = 0;
	
	/**
	 * Decode the frame. 
	 * You must input ARGB(or RGB32) format DIBitmap with width, height depending LoadFrameInfo
	 *
	 * @param[in] ctx					The TIFF decoder context.
	 * @param[in, out] pDIBitmap		It receives the decoded data.
	 * @return TRUE for decode success, FALSE for decode fail or you input wrong format of pDIBitmap.
	 */
	virtual FX_BOOL		Decode(FX_LPVOID ctx, class CFX_DIBitmap* pDIBitmap) = 0;

	/**
	 * Destroy a Tiff decoder.
	 *
	 * @param[in] ctx				The TIFF decoder context.
	 */
	virtual void		DestroyDecoder(FX_LPVOID ctx) = 0;

	/**
	 * Encode an image. 
	 *
	 * @param[in] file_ptr				It receives the encoded TIFF data.
	 * @param[in] ppSource				The pointer of source image list.
	 * @param[in] frames				The number of source image to be encoded(the list size).
	 * @param[in] pAttribute			The attribute information of bitmap.
	 * @return Non-zero means success, otherwise failure.
	 */
	virtual FX_BOOL		Encode(IFX_FileStream* file_ptr, const class CFX_DIBSource** ppSource, FX_INT32 frames, CFX_DIBAttribute** ppAttribute = NULL) = 0;

	/** 
	 * Start a progressive encoder
	 * Initializes the encoding context, and then you can encode the frames to the file. 
	 *
	 * @param[in] file_ptr				It receives the encoded TIFF data. Application only after the FinishEncoder releases the interface.
	 * @param[in] frames				The number of source image to be encoded.
	 * @return A pointer to the progressive encoder context.
	 */
	virtual void*		StartEncoder(IFX_FileStream* file_ptr, FX_INT32 frames) = 0;
	
	/** 
	 * Encode a frame to the TIFF. Application could only do this method frames times according StartEncoder.
	 *
	 * @param[in] pContext				The context pointer create by StartEncoder.
	 * @param[in] pSource				The bitmap is to be encoded in the TIFF.
	 * @param[in] pAttribute			The attribute information of bitmap.
	 */
	virtual FX_BOOL		EncodeFrame(void* pContext, const CFX_DIBSource* pSource, CFX_DIBAttribute* pAttribute = NULL) = 0;
	
	/** 
	 * Complete encoding and destroying context. 
	 *
	 * @param[in] pContext				The context pointer create by StartEncoder.
	 */
	virtual void		FinishEncoder(void* pContext) = 0;
};

/** @brief WEBP module, providing WEBP decoding. */
class ICodec_WebpModule : public CFX_Object
{
public:
	/** The destructor. */
    virtual ~ICodec_WebpModule() {}

	/**
	 * Create a WEBP decoder.
	 *
	 * @param[in] src_buf			The source WEBP encoded data.
	 * @param[in] src_size			The size of the encoded data.
	 * @return The context of the WEBP decoder.
	 */
	virtual FX_LPVOID 	CreateDecoder(FX_LPCBYTE src_buf, size_t src_size) = 0;

	/**
	 * Get the image information.
	 * if output_nComps == 3, then the image should be in FXDIB_Rgb format.
	 * if output_nComps == 4, then the image should be in FXDIB_Argb format.
	 * 
	 *
	 * @param[in] ctx					The WEBP decoder context.
	 * @param[out] width				It receives the image width.
	 * @param[out] height				It receives the image height.
	 * @param[out] output_nComps		It receives the number of output channels.
	 */
	virtual void		GetImageInfo(FX_LPVOID ctx, FX_DWORD& width, FX_DWORD& height, FX_DWORD& output_nComps) = 0;

	/**
	 * Decode the image.
	 *
	 * @param[in] ctx					The WEBP decoder context.
	 * @param[in, out] dest_data		It receives the decoded data.
	 * @param[in] pitch					The row pitch of the provided destination data.
	 */
	virtual FX_BOOL		Decode(FX_LPVOID ctx, FX_LPBYTE dest_data, int pitch) = 0;

	/**
	 * Destroy a WEBP decoder.
	 *
	 * @param[in] ctx				The WEBP decoder context.
	 */
	virtual void		DestroyDecoder(FX_LPVOID ctx) = 0;

//     virtual void        SetIncremental(FX_LPVOID ctx, FX_BOOL incremental) = 0;//
// 
// 	virtual void        SetThread(FX_LPVOID ctx, FX_BOOL isThread) = 0;//
};

//<<<+++OPENSOURCE_END

/** @brief JBIG2 module, providing JBIG2 decoding. */
class ICodec_Jbig2Module : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_Jbig2Module() {}
	/**
	 * Decode the bi-level image encoded by JBIG2.
	 *
	 * @param[in] width					The image width.
	 * @param[in] height				The image height.
	 * @param[in] src_buf				The JBIG2 data.
	 * @param[in] src_size				The size in bytes of the JBIG2 data.
	 * @param[in] global_data			The global JBIG2 data.
	 * @param[in] global_size			The size in bytes of the global JBIG2 data.
	 * @param[in,out] dest_buf			It provides a image buffer and receives the decoded raw image data. 
	 * @param[out] dest_pitch			The row pitch in bytes of the image buffer.
	 * @param[out] pAttribute		Receiving bitmap attribute common information.
	 */
#ifdef _FXM_OPENSOURCE_
	//<<<+++OPENSOURCE_BEGIN LIC==GOOGLE
	virtual FX_BOOL		Decode(FX_DWORD width, FX_DWORD height, FX_LPCBYTE src_buf, FX_DWORD src_size, 
							FX_LPCBYTE global_data, FX_DWORD global_size, FX_LPBYTE dest_buf, FX_DWORD dest_pitch)  = 0;
	//<<<+++OPENSOURCE_END
#else
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	virtual FX_BOOL		Decode(FX_DWORD width, FX_DWORD height, FX_LPCBYTE src_buf, FX_DWORD src_size, 
							FX_LPCBYTE global_data, FX_DWORD global_size, FX_LPBYTE dest_buf, FX_DWORD dest_pitch, CFX_DIBAttribute* pAttribute = NULL)  = 0;
	//<<<+++OPENSOURCE_END
#endif

	/**
	 * Decode the non-embeded bi-level image encoded by JBIG2.
	 * dest_size = height * pitch
	 *
	 * @param[in] file_ptr				The source JBIG2 encoded data reading interface.
	 * @param[in] width					It receives the image width.
	 * @param[in] height				It receives the image height.
	 * @param[in] pitch					It receives the image rowbytes.
	 * @param[out] dest_buf				It receives the decoded image data.
	 * @param[out] pAttribute		Receiving bitmap attribute common information.
	 */
#ifdef _FXM_OPENSOURCE_
	//<<<+++OPENSOURCE_BEGIN LIC==GOOGLE
	virtual FX_BOOL		Decode(IFX_FileRead* file_ptr, FX_DWORD& width, FX_DWORD& height, 
								FX_DWORD& pitch, FX_LPBYTE& dest_buf) = 0;
	//<<<+++OPENSOURCE_END
#else
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	virtual FX_BOOL		Decode(IFX_FileRead* file_ptr, FX_DWORD& width, FX_DWORD& height, 
								FX_DWORD& pitch, FX_LPBYTE& dest_buf, CFX_DIBAttribute* pAttribute = NULL) = 0;
	//<<<+++OPENSOURCE_END
#endif

	virtual void*				CreateJbig2Context()=0;
	
#ifdef _FXM_OPENSOURCE_
	//<<<+++OPENSOURCE_BEGIN LIC==GOOGLE
	virtual FXCODEC_STATUS		StartDecode(void* pJbig2Context, FX_DWORD width, FX_DWORD height, FX_LPCBYTE src_buf, FX_DWORD src_size, 
		FX_LPCBYTE global_data, FX_DWORD global_size, FX_LPBYTE dest_buf, FX_DWORD dest_pitch, IFX_Pause* pPause) = 0;
	//<<<+++OPENSOURCE_END
#else
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	virtual FXCODEC_STATUS		StartDecode(void* pJbig2Context, FX_DWORD width, FX_DWORD height, FX_LPCBYTE src_buf, FX_DWORD src_size, 
		FX_LPCBYTE global_data, FX_DWORD global_size, FX_LPBYTE dest_buf, FX_DWORD dest_pitch, IFX_Pause* pPause, CFX_DIBAttribute* pAttribute = NULL) = 0;
	//<<<+++OPENSOURCE_END
#endif
	
#ifdef _FXM_OPENSOURCE_
	//<<<+++OPENSOURCE_BEGIN LIC==GOOGLE
	virtual FXCODEC_STATUS		StartDecode(void* pJbig2Context, IFX_FileRead* file_ptr,
		FX_DWORD& width, FX_DWORD& height, FX_DWORD& pitch, FX_LPBYTE& dest_buf, IFX_Pause* pPause) = 0;
	//<<<+++OPENSOURCE_END
#else
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	virtual FXCODEC_STATUS		StartDecode(void* pJbig2Context, IFX_FileRead* file_ptr,
		FX_DWORD& width, FX_DWORD& height, FX_DWORD& pitch, FX_LPBYTE& dest_buf, IFX_Pause* pPause, CFX_DIBAttribute* pAttribute = NULL) = 0;
	//<<<+++OPENSOURCE_END
#endif

	virtual FXCODEC_STATUS		ContinueDecode(void* pJbig2Content, IFX_Pause* pPause) =0;

	virtual void				DestroyJbig2Context(void* pJbig2Content) =0;
};

//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
/** @brief Progressive decoder, providing various image decode describes in fx_codec_def.h . */
class ICodec_ProgressiveDecoder : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_ProgressiveDecoder() {}

	/**
	 *	@param[in]	pFile		Pointer to file access object, the caller must keep the buffer 
	 *							all the time until the decoder is destroyed.
	 *	@param[in]	imageType	Told me the image type best, otherwise the system auto detect may slow.
	 *							If you give the wrong type, the system will auto detect the corrected one.
	 *  @param[out] pAttribute	Receiving bitmap attribute common information.
	 *	@return	Only FXCODEC_STATUS_FRAME_READY for can be GetFrames(...).
	 */
	virtual FXCODEC_STATUS		LoadImageInfo(IFX_FileRead* pFile, FXCODEC_IMAGE_TYPE imageType = FXCODEC_IMAGE_UNKNOWN, CFX_DIBAttribute* pAttribute = NULL) = 0;

	/** Get the really image type. Return FXCODEC_IMAGE_UNKNOWN until you get FXCODEC_STATUS_FRAME_READY from LoadImage. */
	virtual FXCODEC_IMAGE_TYPE	GetType() = 0;
	/** Get the image original width. Return zero until you get FXCODEC_STATUS_FRAME_READY from LoadImage. */
	virtual FX_INT32			GetWidth() = 0;
	/** Get the image original height. Return zero until you get FXCODEC_STATUS_FRAME_READY from LoadImage. */
	virtual FX_INT32			GetHeight() = 0;
	/** Get the number of the components. Return zero until you get FXCODEC_STATUS_FRAME_READY from LoadImage. */
	virtual FX_INT32			GetNumComponents() = 0;
	/** Get the bits per component. Return zero until you get FXCODEC_STATUS_FRAME_READY from LoadImage. */
	virtual FX_INT32			GetBPC() = 0;

	/** Set the clip of original image. Effective before GetFrames(...) and after LoadImageInfo(...). */
	virtual void				SetClipBox(FX_RECT* clip) = 0;

	/** Get the image frame numbers, it is a progressive process. 
	 *	The image may be multi-frames, may traversal the whole image.
	 *
	 *	@param[out] frames		It receives the image frame numbers.
	 *	@param[in] pause		Pointer to a structure that can pause the rendering process.
	 * 							Can be NULL if no pausing is needed.
	 *	@return	Only FXCODEC_STATUS_DECODE_READY for can be StartDecode(...), 
	 *			FXCODEC_STATUS_FRAME_TOBECONTINUE for continue.
	 */
	virtual FXCODEC_STATUS		GetFrames(FX_INT32& frames, IFX_Pause* pPause = NULL) = 0;

	/** Start decode the image. Decoding is a progressive process.
	 *	@param[in,out]	pDIBitmap	DIB handle, as the rendering device, cannot 1bppMask or 1bppRgb. 
	 *								It receives the decoded data.
	 *	@param[in] start_x			Left pixel position of the display area in the device coordination
	 *	@param[in] start_y			Top pixel position of the display area in the device coordination
	 *	@param[in] size_x			Horizontal size (in pixels) for displaying the page, must < 65536
	 *	@param[in] size_y			Vertical size (in pixels) for displaying the page, must < 65536
	 *	@param[in] frames			The zero-based frame will be decoded to the device
	 *	@param[in] bInterpol		TRUE for 2D Linear Interpolation. FALSE for Nearest Neighbor Interpolation
	 *	@return The decode status describe in FXCODEC_STATUS, must return FXCODEC_STATUS_TOBECONTINUE for continue
	 */
	virtual FXCODEC_STATUS		StartDecode(class CFX_DIBitmap* pDIBitmap,
									FX_INT32 start_x, FX_INT32 start_y, FX_INT32 size_x, FX_INT32 size_y,
									FX_INT32 frames = 0, FX_BOOL bInterpol = TRUE) = 0;

	/** Continue decode the image.
	 *	@param[in] pause			Pointer to a structure that can pause the rendering process.
	 * 								Can be NULL if no pausing is needed.
	 *	@return The decode status describe in FXCODEC_STATUS
	 */
	virtual FXCODEC_STATUS		ContinueDecode(IFX_Pause* pPause = NULL) = 0;
};

/** @brief JPX encoder, providing jpeg2000 encoding. */
class ICodec_JpxEncoder : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_JpxEncoder(){}

	/**
	 * Get the error message if Encode return FALSE
	 */
	virtual	const CFX_ByteString& GetErrMsg() = 0;
	
	/** 
	 * Set the tile size
	 * The system can not bear more than 65535 tiles in one image
	 * make sure size_x*size_y*65535 > image_width * image_height
	 *
	 * @param[in] size_x	The horizontal tile size
	 * @param[in] size_y	The vertical tile size
	 */
	virtual void	SetSTileSize(int size_x = 256, int size_y = 256) = 0;

	/**
	 * Rotate source image prior to compression(clockwise).
	 * 
	 * @param[in] rotate		1 for 90 degree, 2 for 180 degree, etc.
	 */
	virtual void	Rotate(int rotate) = 0;//0,1,2,3

	/**
	 * Rate control argument
	 * If present, this argument provides rate control information directly in
	 * terms of distortion-length slope values, overriding any information
	 * which may or may not have been supplied via 'AddBitRateValue'.  If the
	 * number of quality layers is  not specified via 'SetCLayers', it will be 
	 * deduced from the number of slope values.  Slopes are inversely related to
	 * bit-rate, so the slopes should decrease from layer to layer. The program 
	 * automatically sorts slopes into decreasing order so you need not worry 
	 * about getting the order right.  For reference we note that a slope value 
	 * of 0 means that all compressed bits will be included by the end of the 
	 * relevant layer, while a slope value of 65535 means that no compressed 
	 * bits will be included in the  layer.  The list of layer slope values must
	 * include at least one non-zero value.
	 *
	 * @param[in] val	in the range of 0 to 65535	
	 */
	virtual void	AddSlopeValue(int val) = 0;

	/**
	 * Bit-rate param
	 * One or more bit-rates, expressed in terms of the ratio between the total
	 * number of compressed bits (including headers) and the product of the
	 * largest horizontal and  vertical image component dimensions.  A value of
	 * 0 may be used in place of the first bit-rate in the list to indicate
	 * that the final quality layer should include all compressed bits. 
	 * Specifying a very large rate target is fundamentally different to using
	 * the value of 0, because the former approach may cause the incremental
	 * rate allocator to discard terminal coding passes which do not lie on the
	 * rate-distortion convex hull.  This means that reversible compression
	 * might not yield a truly lossless representation if you specify 'RateValue'
	 * without a value of 0 for the first rate target, no matter how large the
	 * largest rate target is.
	 * If "SetClayers" is not used, the number of layers is set to the number
	 * of rates specified here. If "SetClayers" is used to specify an actual
	 * number of quality layers, one of the following must be true: 1) the
	 * number of rates specified here is identical to the specified number of
	 * layers; or 2) one, two or no rates are specified using this argument. 
	 * When two rates are specified, the number of layers must be 2 or more and
	 * intervening layers will be assigned roughly logarithmically spaced
	 * bit-rates. When only one rate is specified, an internal heuristic
	 * determines a lower bound and logarithmically spaces the layer rates over
	 * the range.
	 *
	 * param[in] val		May be multi-record of bit-rate value(>= 0.0)
	 */
	virtual void	AddBitRateValue(double val) = 0;

	/**
	 * This argument modifies the behavior of the each of bit-rate, adding by
	 * 'AddBitRateValue', slightly, providing a tolerance specification on the 
	 * achievement of the cumulative layer bit-rates given by that argument.  
	 * It has no effect if layer construction is controlled using the 
	 * 'AddSlopeValue' method.  
	 *
	 * @param[in] tolerance		the tolerance of bit-rate, in range of 0.0 to 50.0
	 */
	virtual void	RateTolerance(FX_FLOAT tolerance) = 0;

	/** 
	 * Set number of quality layer
	 * Actual layers are subject to 'AddSlopeValue' or 'AddBitRateValue' number.
	 *
	 * @param[in] num_layer		May not exceed 16384.
	 */
	virtual void	SetCLayers(int num_layer) = 0;

	/**
	 * Set the default progression order
	 * The four character identifiers have the following interpretation: 
	 * L=layer; R=resolution; C=component; P=position. 
	 * The first character in the identifier refers to the index which progresses 
	 * most slowly, while the last refers to the index which progresses most quickly.
	 *
	 * @param[in] order		In the fx_codec_def.h
	 */
	virtual void	SetCOrder(int order) = 0;

	/**
	 * Set the number of wavelet decomposition levels, or stages.
	 *
	 * @param[in] dwt_levels	May not exceed 32.
	 */
	virtual void	SetCLevels(int dwt_levels = 5) = 0;

	/**
	 * Set whether reversible compression
	 *
	 * @param[in] bReversible	Lossless compress if the value is true
	 */
	virtual void	SetCReversible(FX_BOOL bReversible) = 0;

	/**
	 * Add precinct dimensions (must be powers of 2). 
	 *
	 * Multiple records may be supplied, in which case the first record 
	 * refers to the highest resolution level and subsequent records to 
	 * lower resolution levels. The last specified record is used for any 
	 * remaining lower resolution levels.
	 *
	 * param[in] size_x		Horizontal precinct dimensions
	 * param[in] size_y		Vertical precinct dimensions
	 */
	virtual void	AddCPrecincts(int size_x, int size_y) = 0;

	/**
	 * Set the Nominal code-block dimensions.
	 * (must be powers of 2, no less than 4 and no greater than 1024)
     * Actual dimensions are subject to precinct, tile and image dimensions. 
	 *
	 * @param[in] size_x		Horizontal block dimensions
	 * @param[in] size_y		Vertical block dimensions
	 */
	virtual void	SetCBlk(int size_x, int size_y) = 0;

	/**
	 * If 'TRUE', the code-block partition is aligned so that the last
	 * sample in each nominal block (ignoring the effect of boundaries) 
	 * is aligned at a multiple of the block dimension (a power of 2).  
	 *
	 * @param[in] x		Horizontal dimension align.
	 * @param[in] y		Vertical dimension align.
	 */
	virtual void	SetCAlignBlkLast(FX_BOOL x, FX_BOOL y) = 0;

	/**
	 * Whether or not allow rate prediction
	 * If 'TRUE', the system incrementally constructs conservative 
	 * estimates of the final rate allocation parameters and uses these 
	 * to skip coding passes which are very likely to be discarded during 
	 * rate allocation, else forces encoding and storing of all bit-planes.
	 *
	 * @param[in] be_allow		By default, allow rate prediction
	 */
	virtual void	AllowRatePrediction(FX_BOOL be_allow) = 0;

	/**
	 * If 'TRUE', 16-bit data representations will be employed for 
	 * sample data processing operations (colour transform and DWT) whenever
	 * the image component bit-depth is sufficiently small, else forces the 
	 * use of 32-bit representations.
	 *
	 * @param[in] be_allow		By default, allow shorts
	 */
	virtual void	AllowShorts(FX_BOOL be_allow) = 0;

	/**
	 * Incremental flush period, measured in image lines
	 * By default, the system waits until all compressed data has been
	 * generated, by applying colour transforms, wavelet transforms and block
	 * encoding processes to the entire image, before any of this compressed
	 * data is actually written to the output file.  The present argument may
	 * be used to request incremental flushing, where the compressed data is
	 * periodically flushed to the output file, thereby avoiding the need for
	 * internal buffering of the entire compressed image.  The argument takes a
	 * single parameter, identifying the minimum number of image lines which
	 * should be processed before each attempt to flush new code-stream data. 
	 * The actual period may be larger, if insufficient data has been generated
	 * to progress the code-stream.
	 *
	 * param[in] flush_period		Incremental flush period, must >= 128
	 */
	virtual void	SetFlushPeriod(int flush_period) = 0;

	/**
	 * If 'TRUE', target MSE minimization for colour images.
	 * By default, visual weights will be automatically used for colour imagery
	 * (anything with 3 compatible components).  Turn this off if you want
	 * direct minimization of the MSE over all reconstructed colour components.
	 *
	 * @param[in] no_weights		Using the default weights or not
	 */
	virtual void	NoWeights(FX_BOOL no_weights) = 0;

	/**
	 * This argument is meaningful only when source image is palettized.
     * By default, the palette will be preserved in the destination Jpx stream and 
	 * only the palette indices will be compressed. In many cases, it may be more 
	 * efficient to compress the RGB data as a 24-bit continuous tone image. To 
	 * make sure that this happens, Set 'no_palette == TRUE'
	 *
	 * @param[in] no_palette	Whether the palette be preserved in destination stream
	 */
	virtual void	NoPalette(FX_BOOL no_palette) = 0;

	/**
	 * Aspect ratio of high-res canvas grid.
	 * Identifies the aspect ratio to be used by a conformant JPX reader
	 * when rendering the decompressed image to a display, printer or other
	 * output device.  The aspect ratio identifies ratio formed by dividing the
	 * vertical grid spacing by the horizontal grid spacing, where the relevant
	 * grid is that of the high resolution canvas.  Sub-sampling factors
	 * determine the number of high resolution canvas grid points occupied by
	 * any given image component sample in each direction.  By default
	 * conformantJPX readers are expected to assume a 1:1 aspect ratio on
	 * the high resolution canvas, so that the use of non-identical
	 * sub-sampling factors for an image component implies a required aspect
     * ratio conversion after decompression.
	 *
	 * @param[in] jp2_aspect_ratio
	 */
	virtual void	SetJp2AspectRatio(FX_FLOAT jp2_aspect_ratio) = 0;

	/**
	 * You may use this to explicitly specify a JP2 compatible colour space
	 * description to be included in a JPX stream. If the colour space is
	 * 'sLUM' or 'iccLUM', only one colour channel will be defined, even if the
	 * codestream contains 3 or more components. Note that, the `SetJpxColorSpace' 
	 * argument may be supplied as an alternative or in addition to this argument 
	 * to provide richer colour descriptions or even multiple colour descriptions.  
	 * The present argument must be one of JP2_SPACE_sRGB, JP2_SPACE_sYCC,
	 * JP2_SPACE_sLUM, JP2_SPACE_iccLUM or JP2_SPACE_iccRGB defined in fx_codec_def.h
	 * If the space not standard CS(sLUM or sRGB), the 'SetJp2IccProfile' or
	 * 'SetJp2CSParams' must be provided.
	 *
	 * @param[in] color_space	One of 5 color space illustrates above.
	 */
	virtual void	SetJp2ColorSpace(int color_space) = 0;

	/**
	 * Supplied via the buffer pointed to by the `icc_pfl_buf'argument.  
	 * The internal object makes a copy of this buffer.
	 * The standard ICC header in this buffer identifies its length and
	 * other attributes, from which the object determines whether it
	 * conforms to the restricted ICC profile or not. It is best, if
	 * possible, to provide at least one colour space description which
	 * conforms to the simple ICC profile, or one of the enumerated 
	 * colour spaces, `JP2_SPACE_sRGB', `JP2_SPACE_sYCC' or
	 * `JP2_SPACE_sLUM', since these are JP2-compatible.
	 * To conform to the restricted ICC profile compatible with JP2, the
	 * profile must identify a matrixed 3-colour input space (not a
	 * monitor space, even though these are often functionally equivalent),
     * defined with respect to the XYZ Profile Connection Space (PCS_XYZ).
	 *
	 * @param[in] icc_pfl_buf	The icc profile buffer
	 */
	virtual void	SetJp2IccProfile(FX_LPBYTE icc_pfl_buf) = 0;

	/**
	 * If the space is 'iccLUM', only two parameters must follow, 'gamma' and 'beta',
	 * which identify the tone reproduction curve. And the 'jp2_cs_xy' must equal 'NULL'. 
	 * As examples, the sRGB space has gamma=2.4 and beta=0.055, while NTSC RGB has 
	 * gamma=2.2 and beta=0.099.  
	 * A pure power law has beta=0, but is not recommended due to the ill-conditioned 
	 * nature of the resulting function around 0.
	 * If the space is "iccRGB", all 9 parameters must be provided.
	 *
	 * @param[in] jp2_cs_gamma		Gamma value identify the tone reproduction curve.
	 * @param[in] jp2_cs_beta		Beta value identify the tone reproduction curve.
	 * @param[in] jp2_cs_xy			An array of 6 values hold the X and Y chromaticity info.
	 *								The First 2 parameters hold the X and Y chromaticity
	 *								coordinates of the first (typically red) primary colour.  
	 *								Similarly, the next 4 parameters hold the X,Y coordinates 
	 *								of the second (typically green) and third (typically blue) 
	 *								primary colour.
	 * @param[in] jp2_illum			illuminant information, defined in fx_codec_def.h
	 *								JP2_ILLUMINANT_D50 or JP2_ILLUMINANT_D65		
	 */
	virtual void	SetJp2CSParams(FX_FLOAT jp2_cs_gamma, FX_FLOAT jp2_cs_beta, FX_FLOAT* jp2_cs_xy, int jp2_illum) = 0;

	/**
	 * If the parameter is also supplied, multiple colour descriptions will be written, 
	 * with the JP2 compatible description appearing first. 
	 *
	 * @param[in] color_space		All color spaces are defined in fx_codec_def.h.
	 */
	virtual void	SetJpxColorSpace(int color_space) = 0;
	
	/**
	 * If the `SetJpxCSParams' parameters are omitted, they default to 0.  
	 * Otherwise, the supplied precedence must lie in the range -128 to +127 and the supplied
	 * approximation level must lie in the range 0 to 4. 
	 *
	 */
	virtual void	SetJpxCSParams(int jpx_cs_approx, int jpx_cs_prec) = 0;

	/**
	 * Encode the source dib to compressed JPX stream.
	 * If you want to encode by default parameters, just invoke this method without any setting.
	 * Only support RGB palette and the 1bppCMYK and 8bppCMYK colour spaces are not supported.
	 * Now only support the formats below:
	 *		FXDIB_1bppRGB, FXDIB_8bppRGB, FXDIB_RGB, FXDIB_CMYK, FXDIB_RGB32
	 * 
	 * param[out] dst_buf		It receives the encoded JPX data.
	 * param[out] dst_size		It receives the size of the encoded JPX data. The caller must release the data by FX_Free.
	 * @param[in] pAttribute	The attribute information of bitmap.
	 * @return Non-zero means success, otherwise failure.
	 */
	virtual FX_BOOL	Encode(FX_LPBYTE& dst_buf, FX_DWORD& dst_size, CFX_DIBAttribute* pAttribute = NULL) = 0;
};

/** @brief WEBP encoder, providing WEBP encoding. */
class ICodec_WebpEncoder : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_WebpEncoder(){}

	/**
	 * Set the quality of the webp to be encoded.
	 *
	 * @param[in] quality		The webp quality factor. Between 0 (smallest file) and 100 (biggest). Default is 100.
	 */
	virtual void SetQuality(FX_FLOAT quality) = 0;//0-100/100

	/**
	 * Set the compression method (0=fast, 6=slowest).
	 *
	 * @param[in] method		 Quality/speed trade-off (0=fast, 6=slower-better). Default is 4.
	 */
	virtual void SetMethod(FX_INT32 method) = 0;//0-6/4

	/**
	 * It is recommended to use ARGB input (*argb, argb_stride) for lossless
	 * compression, and YUV input (*y, *u, *v, etc.) for lossy compression.
	 *
	 * @param[in] loseless		Lossless encoding (0=lossy(default), 1=lossless).
	 */
	virtual void SetLoseless(FX_BOOL loseless) = 0;//0/1   / 0

	/**
	 * Only the alpha processing uses the multi-threaded.
	 *
	 * @param[in] isthread		 If non-zero, try and use multi-threaded encoding. Default is  multi-threaded.
	 */
	virtual void SetThread(FX_BOOL isthread) = 0;//0/1//0
	
	/**
	 * Encode the source dib to compressed WEBP stream.
	 * If you want to encode by default parameters, just invoke this method without any setting.
// 	 * Only support RGB palette and the 1bppCMYK and 8bppCMYK colour spaces are not supported.
// 	 * Now only support the formats below:
// 	 *		FXDIB_1bppRGB, FXDIB_8bppRGB, FXDIB_RGB, FXDIB_CMYK, FXDIB_RGB32
     *      RGB	BGR	RGBA	BGRA	RGBX	BGRX WebPPictureImportRGBA
	 * 
	 * param[out] dst_buf		It receives the encoded WEBP data.
	 * param[out] dst_size		It receives the size of the encoded WEBP data. The caller must release the data by FX_Free.
	 * @return Non-zero means success, otherwise failure.
	 */
    virtual FX_BOOL	    Encode(FX_LPBYTE* dst_buf, FX_DWORD& dst_size) = 0;
};

//<<<+++OPENSOURCE_END


class ICodec_Jbig2Encoder : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_Jbig2Encoder(){}
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	/**
	 * Encode an image.
	 * In lossless encoding, there is no global data will be produced.
	 * In lossy encoding, caller need to link the global data and dest buf, in non-embeded mode, to form a completed jb2 stream.
	 *
	 * @param[in] src_buf			The input raw bi-level image buffer.
	 * @param[in] width				The with of the image.
	 * @param[in] height			The height of the image.
	 * @param[in] pitch				The row bytes. 
	 * @param[in] xres				The resolution in horizontal(ppi)
	 * @param[in] yres				The resolution in vertical(ppi)
	 * @param[in] embeded			Whether the encoded data is embeded. embeded data is for pdf.
	 * @param[in] lossless			The flag indicate whether use lossless encoder 
	 * @param[out] dest_buf			It receives the encoded data. The caller must release the data by FX_Free.
	 * @param[out] dest_size		It receives the size of the encoded data.
	 * @param[out] global_data		It receives the global symbols dictionary data. The caller must release the data by FX_Free.
	 * @param[out] global_size		It receives the size of the encoded data.
	 * @param[in] pAttribute		The attribute information of bitmap.
	 * @return Non-zero means success, otherwise failure.
	 */
	virtual FX_BOOL		Encode(FX_LPCBYTE src_buf, int width, int height, int pitch,
							FX_DWORD xres, FX_DWORD yres,
							FX_BOOL embeded, FX_BOOL lossless,
							FX_LPBYTE& dest_buf, FX_DWORD& dest_size,
							FX_LPBYTE& global_data, FX_DWORD& global_size, CFX_DIBAttribute* pAttribute = NULL) = 0;
//<<<+++OPENSOURCE_END
};
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
class ICodec_GifEncoder : public CFX_Object
{
public:
	/** The destructor. */
	virtual ~ICodec_GifEncoder(){}
	/**
	 * Encode the source dib array into compressed GIF stream.
	 * If you want to encode by default parameters, just invoke this method with NULL CFX_DIBAttribute pointer.
	 * 
	 * param[in] ppSource		The source dib array. Only support FXDIB_1/8bppRgb format.
	 * param[in] nFrames		The frame number of the source dib array.
	 * param[in] pGlobalPal		The global palette pointer.
	 * param[in] dwGlobalPalNum	The number of global palette.
	 * param[in] dwLogicWidth	The logic scene width. Should not be 0.
	 * param[in] dwLogicHeight	The logic scene height. Should not be 0.
	 * param[out] dst_buf		It receives the encoded GIF data. The caller should set the dst_buf NULL when encode gif source dib first time.
	 * param[out] dst_size		It receives the size of the encoded GIF data. The caller must release the data by FX_Free.
	 * @param[in] ppAttribute	The attribute information array of bitmap.
	 * 
	 * User should creat this array with the same scene size by Clone(clip of scene size)/StretchTo(clip of scene size) method.
	 * NOTE: ppAttribute[n]->m_nGifLeft + ppSource[n]->GetWidth() <= LogicSceceWidth;
	 *		 ppAttribute[n]->m_nGifTop + ppSource[n]->GetHeight() <= LogicSceceHeight;
	 * The palette of ppSource[0] would be used as global palette.
	 * 
	 * @return Non-zero means success, otherwise failure.
	 */
	virtual FX_BOOL		Encode(const CFX_DIBSource** ppSource, FX_DWORD nFrames, 
								FX_DWORD* pGlobalPal, FX_DWORD dwGlobalPalNum, 
								FX_DWORD dwLogicWidth, FX_DWORD dwLogicHeight,
								FX_LPBYTE& dst_buf, FX_DWORD& dst_size, 
								CFX_DIBAttribute** ppAttribute = NULL) = 0;
};

class ICodec_BmpEncoder : public CFX_Object
{
public:
	/**
	 * Encode the source dib to BMP file stream.
	 * Only support RGB color space.
	 * 
	 * param[in] pSource		The source dib.
	 * param[out] dst_buf		It receives the encoded BMP data. The caller should set the dst_buf NULL when encode gif source dib first time.
	 * param[out] dst_size		It receives the size of the encoded BMP data. The caller must release the data by FX_Free.
	 * @param[in] pAttribute	The attribute information of bitmap.
	 * 
	 * @return Non-zero means success, otherwise failure.
	 */
	virtual FX_BOOL		Encode(CFX_DIBSource* pSource, FX_LPBYTE& dst_buf, FX_DWORD& dst_size, CFX_DIBAttribute* pAttribute = NULL) = 0;
};
//<<<+++OPENSOURCE_END

/** @brief ICC module, providing ICC color profile processing. */
class ICodec_IccModule : public CFX_Object
{
public:
	typedef enum {	/**< ICC color space */
		IccCS_Unknown = 0,
		IccCS_XYZ,
		IccCS_Lab,
		IccCS_Luv,
		IccCS_YCbCr,
		IccCS_Yxy,
		IccCS_Hsv,
		IccCS_Hls,
		IccCS_Gray,
		IccCS_Rgb,
		IccCS_Cmyk,
		IccCS_Cmy
	} IccCS;

	typedef struct _IccParam {
		FX_DWORD	Version;		/**< The version of IccParam struct */
		IccCS		ColorSpace;
		FX_DWORD	dwProfileType;	/**< The type of custom params below, descripted in Icc_PARAMTYPE_XXX */
		FX_DWORD	dwFormat;		/**< The format described in Icc_FORMAT_XXX */

		FX_LPBYTE	pProfileData;
		FX_DWORD	dwProfileSize;

		double		Gamma;
	}IccParam;

	/** The destructor. */
	virtual ~ICodec_IccModule() {}

	/**
	 * Detect the profile color space.
	 *
	 * @param[in] pProfileData			The profile data.
	 * @param[in] dwProfileSize			The profile data size.
	 * @return The color space of ICC profile.
	 */
	virtual IccCS			GetProfileCS(FX_LPCBYTE pProfileData, unsigned int dwProfileSize) = 0;

	/**
	 * Detect the profile color space.
	 *
	 * @param[in] pFile					Pointer to a file read object. 
	 * @return The color space of ICC profile.
	 */
	virtual IccCS			GetProfileCS(IFX_FileRead* pFile) = 0;

	/** 
	 * Create a transform from source color space to destination color space.
	 * The obtained transform emulates the device described by the "Proofing" profile. 
	 * Useful to preview final result without rendering to the physical medium. 
	 * To enable proofing Icc_FLAGS_SOFTPROOFING: does emulate the Proofing device.
	 *
	 * @param[in] pIptParam				The input IccParam pointer.
	 * @param[in] pOutParam				The output IccParam pointer.
	 * @param[in] pProofParam			The proofing IccParam pointer, NULL if don't use "Proofing" profile.
	 * @param[in] dwIntent				The intent of transform from src to dst.
	 * @param[in] dwPrfFlag				A combination of bit-field constants described in Icc_FLAGS_XXX above.
	 * @param[in] dwPrfIntent			The intent of proofing intent.
	 * @param[in] dwPrfFlag				The combination of proofing combination.
	 *
	 * @return A handle to a transform object on success, NULL on error. This handle will be free when
	 *		CCodec_IccModule destructed, so it should not be destroy by DestroyTransform function.
	 */
	virtual FX_LPVOID	CreateTransform(ICodec_IccModule::IccParam* pInputParam,
								ICodec_IccModule::IccParam* pOutputParam,
								ICodec_IccModule::IccParam* pProofParam = NULL, 
								FX_DWORD dwIntent = Icc_INTENT_PERCEPTUAL, 
								FX_DWORD dwFlag = Icc_FLAGS_DEFAULT,
								FX_DWORD dwPrfIntent = Icc_INTENT_ABSOLUTE_COLORIMETRIC, 
								FX_DWORD dwPrfFlag = Icc_FLAGS_SOFTPROOFING
								) = 0;
	
	/**
	 * Create a transform from some source color space to sRGB.
	 * Note: This is a specified transform which destination stream by Translate/TranslateScanline
	 * is in memory order is always BGR. The source order is indicate by dwSrcFormat.
	 * Note: Deprecated, the interface may need cancel.
	 * 
	 *
	 * @param[in] pProfileData			The profile data.
	 * @param[in] dwProfileSize			The profile data size.
	 * @param[in] nComponents			External specified count of components.
	 * @param[in] intent				The transform intent described in Icc_INTENT_XXX.
	 * @param[in] dwSrcFormat			The input format described in Icc_FORMAT_XXX.		
	 *
	 * @return The transform from ICC to sRGB.
	 */
	virtual FX_LPVOID	CreateTransform_sRGB(FX_LPCBYTE pProfileData, unsigned int dwProfileSize, int nComponents, int intent = 0, 
								FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT) = 0;

	/**
	 * Create a transform from some source color space to CMYK.
	 * Note: Deprecated, the interface may need cancel.
	 *
	 * @param[in] pSrcProfileData		The profile data.
	 * @param[in] dwSrcProfileSize		The source profile data size.
	 * @param[in] nSrcComponents		External specified count of components.
	 * @param[in] pDstProfileData		The CMYK profile data.
	 * @param[in] dwDstProfileSize		The profile data size.
	 * @param[in] intent				The transform intent described in Icc_INTENT_XXX.
	 * @param[in] dwSrcFormat			The input format described in Icc_FORMAT_XXX.
	 * @param[in] dwDstFormat			The output format described in Icc_FORMAT_XXX.
	 *
	 * @return The transform from ICC some color space to ICC CMYK.
	 */
	virtual FX_LPVOID	CreateTransform_CMYK(FX_LPCBYTE pSrcProfileData, unsigned int dwSrcProfileSize, int nSrcComponents, 
								FX_LPCBYTE pDstProfileData, unsigned int dwDstProfileSize, int intent = 0, 
								FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT, 
								FX_DWORD dwDstFormat = Icc_FORMAT_DEFAULT
								) = 0;

	/**
	 * Destroy a transform.
	 *
	 * @param[in] pTransform			The color transform to be destroyed.
	 */
	virtual void			DestroyTransform(FX_LPVOID pTransform) = 0;

	/**
	 * Translate color.
	 *
	 * @param[in] pTransform			The transform context.
	 * @param[in] pSrcValues			Input the color components in ICC color space.
	 *									The stream memory order according the flag Icc_FORMAT_XXX.
	 * @param[in,out] pDestValues		It receives color components in some color space you created.
	 *									The stream memory order according the flag Icc_FORMAT_XXX.
	 */
	virtual void			Translate(FX_LPVOID pTransform, FX_FLOAT* pSrcValues, FX_FLOAT* pDestValues) = 0;

	/**
	 * Translate an image line into 1 channel gray, 3 channels(8bpc) sRGB or 4 channels(8bpc) CMYK.
	 * The source component data must be encoded as 8 bit, with default encoding min/max.
	 * NOTE: the destination address and source address can be SAME if src components >= dst components! 
	 *
	 * @param[in] pTransform			The transform context.
	 * @param[in,out] pDest				It receives the translated scanline data.
	 *									The stream memory order according the flag Icc_FORMAT_XXX.
	 * @param[in] pSrc					Input the source scanline.
	 *									The stream memory order according the flag Icc_FORMAT_XXX.
	 * @param[in] pixels				The number of pixels in the scanline.
	 */
	virtual void			TranslateScanline(FX_LPVOID pTransform, FX_LPBYTE pDest, FX_LPCBYTE pSrc, int pixels) = 0;
};

void AdobeCMYK_to_sRGB(FX_FLOAT c, FX_FLOAT m, FX_FLOAT y, FX_FLOAT k, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B);
void AdobeCMYK_to_sRGB1(FX_BYTE c, FX_BYTE m, FX_BYTE y, FX_BYTE k, FX_BYTE& R, FX_BYTE& G, FX_BYTE& B);
FX_BOOL MD5ComputeID(FX_LPCVOID buf, FX_DWORD dwSize, FX_BYTE ID[16]);

//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
/** @brief DIB Attribute, providing the common attribute for dib bitmap. */
class CFX_DIBAttribute : public CFX_Object
{
public:
	CFX_DIBAttribute();
	~CFX_DIBAttribute();
	/** Horizontal resolution, -1 means the bitmap doesn't contain this information, 
	 *  0 or 1 means the user should use default dpi value. 
	 *  JBIG2 cannot get dpi information now.
	 *	Read-Only member.
	 */
	FX_INT32		m_nXDPI;
	/** Vertical resolution, -1 means the bitmap doesn't contain this information, 
	 *  0 or 1 means the user should use default dpi value. 
	 *  JBIG2 cannot get dpi information now.
	 *	Read-Only member.
	 */
	FX_INT32		m_nYDPI;
	/** The aspect ratio, -1.0 means the bitmap doesn't contain this information. Usually read from GIF/JPEG2000 image.
	 *	Read-Only member.
	 */
	FX_FLOAT		m_fAspectRatio;
	/** resolution unit, described by FXCODEC_RESUNIT_XXX. 
	 *	Read-Only member.
	 */
	FX_WORD			m_wDPIUnit;
	/** The author, like "Foxit Corporation". BMP/JBIG2 cannot support this now. Editable member.*/
	CFX_ByteString	m_strAuthor;
	/** The last edited time of the bitmap. 
	 *  Use format: 'year' in 4 or 2 bytes, others in 2 bytes each, at most 20 bytes, the last byte is 0x00.
	 *  BMP/JBIG2 cannot support this now.
	 *	Editable member.
	 */
	FX_BYTE			m_strTime[20];

	/** The position of current bitmap in gif file. */
	FX_INT32		m_nGifLeft;
	FX_INT32		m_nGifTop;
	/** The local palette of current frame of gif image. Default NULL. */
	FX_DWORD*		m_pGifLocalPalette;
	/** The number of local palette. */
	FX_DWORD		m_nGifLocalPalNum;

	/** The compress type of bmp buffer, defined in BMP_COMPRESS_XXX. */
	FX_INT32		m_nBmpCompressType;

	class IFX_DIBAttributeExif* m_pExif;
};

/** @brief Camera information for JPEG/TIFF. */
class IFX_DIBAttributeExif : public CFX_Object
{
public:
	virtual ~IFX_DIBAttributeExif() {};
	virtual FX_BOOL		GetInfo(FX_WORD tag, FX_LPVOID val) = 0;
};
//<<<+++OPENSOURCE_END

//<<<+++OPENSOURCE_MUST_BEGIN
#endif	// _FX_CODEC_H_
//<<<+++OPENSOURCE_MUST_END

/** @} */


